阿里:2017春季实习生招聘面试题及答案解析
给你们找到了阿里春季面试题,并且还有答案。应届生要进BAT的赶紧看下面试题,往届生赶紧来测试下自己的水平啊。
1、iBatis相比JDBC优势的优势有哪些?
答:简单易上手、开发速度快、面向对象,数据库可移植。
(此处应该将优缺点一起分析,才是满意得到回答)
延伸学习:
MyBatis和iBatis的区别:
ibatis本是apache的一个开源项目,2010年这个项目由apache software foundation 迁移到了google code,并且改名为mybatis
(1)Mybatis实现了接口绑定,使用更加方便:
在ibatis2.x中我们需要在DAO的实现类中指定具体对应哪个xml映射文件,而Mybatis实现了DAO接口与xml映射文件的绑定,
(2)对象关系映射的改进,效率更高
iBatis:
优点 : 代码量减少、简单易上手、SQL语句和代码分离(便于修改)、数据库可移植
缺点:SQL语句需要自己写、参数只能有一个
Hibernate:
优点:对象关系数据库映射、完全面向对象、提供缓存机制、HQL编程
缺点:不能灵活使用原生SQL、 无法对SQL优化、全表映射效率低下、N+1的问题
JDBC、iBatis、Hibernate明显对比:
JDBC更为灵活,更加有效率,系统运行速度快。但是代码繁琐复杂,有的时候用了存储过程就不方便数据库移植了。
hibernate,iBatis 关系数据库框架,开发速度快,更加面向对象,可以移植更换数据库,但影响系统性能。
JDBC:手动
手动写sql,不能直接传入一个对象、不能直接返回一个对象。
iBatis的特点:半自动化
手动写sql,能直接传入一个对象、能直接返回一个对象。
Hibernate:全自动
不写sql,自动封装,能直接传入一个对象、能直接返回一个对象。
2、PrepareStatement相比statement,有哪些优点?
答:
(1)直接使用Statement,驱动程序一般不会对sql语句作处理而直接交给数据库;
使用PreparedStament,形成预编译的过程,并且会对语句作字符集的转换(至少在sql server)中如此。
如此,有两个好处:对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;另外,可以比较好地解决系统的本地化问题。
(2)PreparedStatement还能有效的防止危险字符的注入,也就是sql注入的问题。(但是必须使用“对?赋值的方法”才管用)
3、TCP/IP对应于OSI七层模型的哪些层?
答:
OSI七层模型分别是:应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。
TCP/IP协议不是TCP和IP协议的合称,而是指因特网整个TCP/IP协议族。从协议分层模型方面来看,TCP/IP由四个层次组成:网络接口层、网络层、传输层和应用层。
4、为什么3次握手,4次挥手?
3次握手建立连接:
第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)即握手信号。
第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
4次挥手断开连接:
对于一个已经建立的连接,TCP使用改进的4次挥手来释放连接(使用一个带有FIN附加标记的报文段)。TCP关闭连接的步骤如下:
第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。
第二步,主机B收到这个FIN报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段)。
第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个FIN报文段。
第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示连接彻底释放。
5、进程和线程区别是什么?
答:
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。
进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。
线程与进程的区别归纳:
地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
调度和切换:线程上下文切换比进程上下文切换要快得多。
6、多线程什么情况下执行wait?
答:在同步代码块中,即对象只有获得了互斥锁之后才可以调用wait()方法。
延伸学习(1):
sleep( )和wait( n)、wait( )的区别:
sleep方法:是Thread类的静态方法,当前线程将睡眠n毫秒,线程进入阻塞状态。当睡眠时间到了,会解除阻塞,进行可运行状态,等待CPU的到来。睡眠不释放锁(如果有的话)
wait方法:是Object的方法,必须与synchronized关键字一起使用,线程进入阻塞状态,当notify或者notifyall被调用后,会解除阻塞。但是,只有重新占用互斥锁之后才会进入可运行状态。睡眠时,释放互斥锁。
join( )方法:
当前线程调用,则其它线程全部停止,等待当前线程执行完毕,接着执行。
suspend( )和resume( )方法:
两个方法配套使用,前者使线程进入阻塞状态,并且不会自动恢复,必须等待resume( )方法被调用,才能使得线程重新进入可执行状态。
典型用法,用于等待另一个线程产生的结果的情形,测试发现结果还没有产生后,让线程阻塞。当另一个线程产生了结果后,调用resume( )使其恢复。
yield() 方法:
yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。
延伸学习(2):
线程的的生命周期:创建状态、就绪状态(可运行状态)、运行状态、阻塞状态、消亡状态。
7、Spring容器如何加载?
答:
在应用程序web.xml中做了以下配置信息时,当启动Web容器时就会自动加载spring容器。
ContextLoaderListener!!!
org.springframework.web.context.ContextLoaderListener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ContextLoaderListener类实现了javax.servlet.ServletContextListener接口并且继承了org.springframework.web.context.ContextLoader类。ServletContextListener事件类是Web容器的一部分,处理Web应用的Servlet上下文(context)的监听。实现ServletContextListener接口中的contextInitialized和contextDestroyed方法。当Web容器启动时会自动调用contextInitialized方法,进行初始化Spring Web应用程序上下文,主要加载web.xml中contextConfigLocation的配置文件;当Web容器关闭之前会调用contextDestroyed方法,进行销毁Spring Web应用程序上下文。ContextLoader类实现了Spring上下文初始化的工作,执行initWebApplicationContext方法返回WebApplicationContext。
延伸学习:
如果要spring-mvc的话,需要在web.xml文件中配置如下:
DispatchServlet!!!
org.springframework.web.servlet.DispatchServlet
<servlet>
<servlet-name>simpleSpringMVC/servlet-name>
<servlet-class>org.springframework.web.servlet.DispatchServlet</servlet-class>
<load-on-startup>1</load-on-startup></servlet><servlet-mapping>
<servlet-name>simpleSpringMVC</servlet-name>
<url-pattern>*.htm</url-pattern></servlet-mapping>
</servlet>
8、Servlet生命周期(什么时候destory)?
答:Servlet的生命周期是由Servlet容器(即Web服务器)来控制的,通过简单的概括可以分为4步:
(1)Servlet类加载
(2)实例化Servlet
(3)Servlet提供服务
(4)销毁Servlet
当Web应用被终止时,Servlet容器会先调用Web应用中所有的Servlet对象的destroy( )方法,然后再销毁Servlet对象。
9、10G数据,每一条是一个qq号,统计出现频率最多的qq号。
答:
首先你要注意到,数据存在服务器,存储不了(内存存不了),要想办法统计每一个qq出现的次数。
比如,因为内存是1g,首先 你用hash 的方法,把qq分配到10个(这个数字可以变动,比较)文件(在硬盘中)。
相同的qq肯定在同一个文件中,然后对每一个文件,只要保证每一个文件少于1g的内存,统计每个qq的次数,可以使用hash_map(qq, qq_count)实现。然后,记录每个文件的最大访问次数的qq,最后,从10个文件中找出一个最大,即为所有的最大。更多读者可以参见此文:海量数据处理面试题集锦与Bit-map详解 。
那若面试官问有没有更高效率的解法之类的?这时,你可以优化一下,但是这个速度很快,hash函数,速度很快,他肯定会问,你如何设计,用bitmap也行。
10、hashmap实现原理
http://blog.csdn.net/qq_25827845/article/details/64543056
11、数组和链表的比较
答:
数组静态分配内存,链表动态分配内存;
数组在内存中连续,链表不连续;
数组元素在栈区,链表元素在堆区;
数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。
12、ArrayList和Linkedlist对比
答:
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
提升能力从勤学开始!
达内4月Android开发免费训练营开始报名啦,教最新最流行的技术,学最符合企业需要的项目,让你毕业等于拥有工作经验,入职无需适应,直接上手,做企业争相抢聘的Android工程师。名额有限,阅读原文马上抢名额吧!
想知道怎样才能入门Andorid? 学Andorid到底能不能赚到钱?零基础能不能学会?
回复「安卓前景」给你看行业前景和钱景。
回复「安卓课程」给你看10分详细课程介绍。
咨询就业和课程具体开课细节请直接回复「您的姓名+微信号+安卓」,老师将详细为你解答。
各类干货和励志鸡血,更有各种好玩好看的资讯!
长按图片识别二维码关注我们,
公众号回复“MJ”或点击阅读原文免费试听学习
Android开发干货课程!